package com.cljh.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.cljh.bean.Files;
import com.cljh.config.AuthAccess;
import com.cljh.controller.page.PageBean;
import com.cljh.controller.page.Code;
import com.cljh.controller.page.Result;
import com.cljh.mapper.FileMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.List;

/**
 * 文件上传相关接口
 */
@RestController
@RequestMapping("/file")

public class FileController {

    @Autowired
    FileMapper fileMapper;
    @Value("${files.upload.path}")
    private String path;

//    @Value("${server.ip}")
//    private String ip;

    /**
     * 文件上传接口
     *
     * @param file 前端上传的文件
     * @return
     * @throws IOException
     */
    @AuthAccess
    @PostMapping("/upload")
    public String upload(MultipartFile file) throws IOException {
        System.out.println(file);
        String name = file.getOriginalFilename();//文件名称
        String type = FileUtil.extName(name);//文件类型
        long size = file.getSize();//文件大小
        String url = null;
        //先创建路径
        File uploadParentFile = new File(path);//本地路径
        //判断文件夹是否存在
        if (!uploadParentFile.exists()) {
            uploadParentFile.mkdirs();//创建文件夹
        }
        //设置唯一标识
        String uuid = IdUtil.fastSimpleUUID();

        String uuidName = uuid + StrUtil.DOT + type;
        String path = uploadParentFile + "/" + uuidName;
        System.out.println(path);
        File uploadFile = new File(path);
        //上传文件到硬盘
        file.transferTo(uploadFile);
        //获取md5
        String md5 = SecureUtil.md5(uploadFile);

        Files files = fileMapper.selectByMd5(md5);
        if (files == null) {//数据库不存在
            Files files1 = new Files();
            files1.setFileName(name);
            files1.setType(type);
            files1.setSize(size);
            /**
             * TODO 修改端口号
             */
            //            url = "http://192.168.175.12:8088/file/" + uuidName;
//            url= "http://47.100.16.54:8088/file/"+uuidName;
            url = "http://localhost:8088/file/" + uuidName;
//            url = "http://101.43.113.122:8088/file/" + uuidName;
            files1.setUrl(url);
            files1.setMd5(md5);
            fileMapper.save(files1);

        } else {//数据库存在
            url = files.getUrl();
            uploadFile.delete();
        }
        System.out.println(url);
        return url;
    }

    /**
     * 文件下载接口
     *
     * @param uuidName String url="http://localhost:8088/file/{uuidName}"
     * @param response
     * @throws IOException
     */
    @AuthAccess
    @GetMapping("/{uuidName}")
    public void download(@PathVariable String uuidName, HttpServletResponse response) throws IOException {
        //根据文件的唯一标识码获取文件
        System.out.println(uuidName);
        File file = new File(path + uuidName);

        if (file.length() > 1000000) {
            response.setHeader("Accept-Ranges", "bytes");
            response.setContentLength(Math.toIntExact(file.length()));
        }


        // 设置输出流的格式,告诉浏览器输出内容为流
        response.setContentType("application/octet-stream");
        // 设置文件名
        response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(uuidName, "UTF-8"));
        //设置输出流的格式
        ServletOutputStream outputStream = response.getOutputStream();
        //读取上传文件字节流
        outputStream.write(FileUtil.readBytes(file));
        outputStream.flush();
        outputStream.close();
    }

    @AuthAccess
    @GetMapping("/front/all")
    public Result frontAll() {
        List<Files> files = fileMapper.selectAll();
        Integer code = files != null ? Code.GET_OK : Code.GET_ERR;
        String msg = files != null ? "查询到信息" : "未查询到信息";
        return new Result(code, files, msg);
    }

    @DeleteMapping("/{id}")
    public Result deleteId(@PathVariable Integer id) {
        Files files = fileMapper.selectId(id);
        String url = files.getUrl();
        int i = url.lastIndexOf("/");
        String urlName = url.substring(i + 1, url.length());
        File file = new File(path + "/" + urlName);
        if (file.exists()) {
            file.delete();
        }
        int delete = fileMapper.delete(id);
        boolean b = delete > 0;
        Integer code = b ? Code.DELETE_OK : Code.DELETE_ERR;
        String msg = b ? "删除一个成功" : "删除一个失败";

        return new Result(code, b, msg);
    }


    @PostMapping("/{pn}/{size}")
    public Result selectProduct(@PathVariable(value = "pn") Integer pn, @PathVariable(value = "size") Integer size, @RequestBody Files f) {

        String fileName = f.getFileName();
        if (fileName != null && fileName.length() > 0) {
            fileName = "%" + fileName + "%";
        }
        String type = f.getType();
        if (type != null && type.length() > 0) {
            type = "%" + type + "%";
        }

        f.setType(type);
        f.setFileName(fileName);
        Integer begin = (pn - 1) * size;


        int count = fileMapper.count(f);
        List<Files> files = fileMapper.selectAllByCondition(begin, size, f);


        PageBean<Files> filesPageBean = new PageBean<>();
        filesPageBean.setTotalCount(count);
        filesPageBean.setRows(files);

        Integer code = files != null ? Code.GET_OK : Code.GET_ERR;
        String msg = files != null ? "查询到信息" : "未查询到信息";

        return new Result(code, filesPageBean, msg);
    }

    @DeleteMapping
    public Result deleteIds(@RequestBody List<Integer> ids) {
        for (Integer i : ids) {
            Files files = fileMapper.selectId(i);
            String url = files.getUrl();
            int k = url.lastIndexOf("/");
            String urlName = url.substring(k + 1, url.length());
            File file = new File(path + "/" + urlName);
            if (file.exists()) {
                file.delete();
            }
        }
        int i = fileMapper.deleteByIds(ids);
        boolean b = i > 0;
        Integer code = b ? Code.DELETE_OK : Code.DELETE_ERR;
        String msg = b ? "删除成功" : "删除失败";
        return new Result(code, b, msg);
    }

    @AuthAccess
    @PostMapping("/all")
    public Result selectAll(@RequestBody Files files) {
        String fileName = files.getFileName();
        if (fileName != null && fileName.length() > 0) {
            files.setFileName("%" + fileName + "%");
        }

        String type = files.getType();
        if (type != null && type.length() > 0) {
            files.setType("%" + type + "%");
        }

        List<Files> files1 = fileMapper.selectFiles(files);
        Integer code = files1 != null ? Code.GET_OK : Code.GET_ERR;
        String msg = files1 != null ? "查到信息" : "未查到信息";
        return new Result(code, files1, msg);
    }

    @GetMapping("/detail/{id}")
    public Result getDetail(@PathVariable Integer id) {
        Files files = fileMapper.selectId(id);

        Integer code = files != null ? Code.GET_OK : Code.GET_ERR;
        String msg = files != null ? "查询到信息" : "未查询到信息";
        return new Result(code, files, msg);
    }
}
